package com.zlp.mall.portal.modules.oms.service.impl;

import java.util.ArrayList;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zlp.mall.common.enums.StatusEnum;
import com.zlp.mall.common.util.BeanToUtils;
import com.zlp.mall.portal.config.SessionMap;
import com.zlp.mall.portal.modules.oms.dto.req.CarAddReq;
import com.zlp.mall.portal.modules.oms.dto.resp.CarItemResp;
import com.zlp.mall.portal.modules.oms.mapper.CartItemMapper;
import com.zlp.mall.portal.modules.oms.model.CartItem;
import com.zlp.mall.portal.modules.oms.service.CartItemService;
import com.zlp.mall.portal.modules.pms.model.Product;
import com.zlp.mall.portal.modules.pms.model.SkuStock;
import com.zlp.mall.portal.modules.pms.service.ProductService;
import com.zlp.mall.portal.modules.pms.service.SkuStockService;
import com.zlp.mall.portal.modules.ums.model.Member;
import com.zlp.mall.portal.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 购物车表 服务实现类
 * </p>
 *
 * @author ZouLiPing
 * @since 2021-10-15
 */
@Service
@RequiredArgsConstructor
@Slf4j(topic = "CartItemServiceImpl")
public class CartItemServiceImpl extends ServiceImpl<CartItemMapper, CartItem> implements CartItemService {

    private final ProductService productService;
    private final CartItemMapper cartItemMapper;
    private final SkuStockService skuStockService;
    private final SessionMap sessionMap;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CarItemResp> addCar(CarAddReq carAddReq) {

        log.info("addCar.req carAddReq={}", JSON.toJSONString(carAddReq));
        List<CarItemResp> carItemRespList = new ArrayList<>();
        Long productId = carAddReq.getProductId();
        Long productSkuId = carAddReq.getProductSkuId();

        Member member = SecurityUtils.getUser();
        CartItem cartItem = getCarItem(productId, productSkuId, member.getId());

        // 获取商品信息
        Product product = productService.getProductById(productId);
        SkuStock skuStock = skuStockService.getBySkuId(productSkuId);
        if (Objects.isNull(cartItem)) {
            addCartItem(carAddReq, productSkuId, product, member, skuStock);
        } else {
            LambdaUpdateWrapper<CartItem> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(CartItem::getId, cartItem.getId())
                    .set(CartItem::getQuantity, carAddReq.getQuantity() + 1)
                    .set(CartItem::getModifyDate, DateUtil.date());
            this.update(updateWrapper);
        }
        CarItemResp carItemResp = BeanToUtils.doToDto(cartItem, CarItemResp.class);
        carItemRespList.add(carItemResp);
        return carItemRespList;
    }

    @Override
    public List<CarItemResp> cartList(LambdaQueryWrapper<CartItem> queryWrapper) {

        List<CarItemResp> carItemRespList = cartItemMapper.cartList(queryWrapper);
        return carItemRespList;
    }

    @Override
    public int getCartSum() {

        Member member = sessionMap.getSessionUser();
        if (Objects.isNull(cartItemMapper.getCartSum(member.getId()))) return 0;

        return cartItemMapper.getCartSum(member.getId());
    }

    @Override
    public boolean updateQuantity(Long id, Integer quantity) {

        log.info("delete.req id={},quantity={}", id, quantity);
        LambdaUpdateWrapper<CartItem> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CartItem::getQuantity, quantity);
        updateWrapper.eq(CartItem::getId, id);
        this.update(updateWrapper);
        return Boolean.TRUE;
    }

    @Override
    public boolean delete(List<Long> ids) {

        log.info("delete.req ids={}", ids);
        LambdaUpdateWrapper<CartItem> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CartItem::getDeleteStatus, 0);
        updateWrapper.in(CartItem::getId, ids);
        this.update(updateWrapper);
        return Boolean.TRUE;
    }

    private CartItem getCarItem(Long productId, Long productSkuId, Long memberId) {

        LambdaQueryWrapper<CartItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CartItem::getProductId, productId)
                .eq(CartItem::getProductSkuId, productSkuId)
                .eq(CartItem::getMemberId, memberId);
        return this.getOne(queryWrapper);
    }

    /**
     * 添加购物车
     *
     * @param carAddReq
     * @param productSkuId
     * @param product
     * @param member
     * @param skuStock
     * @date: 2021/10/15 15:03
     * @return: com.zlp.mall.portal.modules.oms.model.CartItem
     */
    private CartItem addCartItem(CarAddReq carAddReq, Long productSkuId, Product product, Member member, SkuStock skuStock) {
        CartItem cartItem = new CartItem();
        cartItem.setProductId(product.getId());
        cartItem.setProductSkuId(productSkuId);
        cartItem.setMemberId(member.getId());
        cartItem.setQuantity(carAddReq.getQuantity());
        cartItem.setPrice(product.getPrice());
        cartItem.setProductPic(product.getPic());
        cartItem.setProductName(product.getName());
        cartItem.setProductSubTitle(product.getSubTitle());
        cartItem.setProductSkuCode(skuStock.getSkuCode());
        cartItem.setMemberNickname(member.getNickname());
        cartItem.setModifyDate(DateUtil.date());
        cartItem.setCreateDate(DateUtil.date());
        cartItem.setDeleteStatus(StatusEnum.NORMAL.getValue());
        cartItem.setProductCategoryId(product.getProductCategoryId());
        cartItem.setProductBrand(product.getBrandName());
        cartItem.setProductSn(product.getProductSn());
        cartItem.setProductAttr(skuStock.getSpData());
        this.save(cartItem);
        return cartItem;
    }
}
